﻿using Exam.Repository.Interface;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Exam.Repository.instance
{
    public class MySqlRepository<T> : IRepository<T> where T : class, new()
    {
        private readonly DbContext _dbcontext;

        public MySqlRepository(DbContext dbcontext)
        {
            _dbcontext = dbcontext;
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="t"></param>
        public void Add(T t)
        {
            _dbcontext.Set<T>().Add(t);
        }
        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="ie"></param>
        public void AddRange(IEnumerable<T> ie)
        {
            _dbcontext.Set<T>().AddRange(ie);
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="t"></param>
        public void Delete(T t)
        {
            _dbcontext.Set<T>().Remove(t);
        }
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ie"></param>
        public void DeleteRange(IEnumerable<T> ie)
        {
            _dbcontext.Set<T>().RemoveRange(ie);
        }
        /// <summary>
        /// 条件查询
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public IQueryable<T> QueryAll(Expression<Func<T, bool>>? where)
        {
            IQueryable<T> iq = _dbcontext.Set<T>();
            if (where != null)
            {
                iq = iq.Where(where);
            }
            return iq;
        }
        /// <summary>
        /// 排序查询
        /// </summary>
        /// <typeparam name="type"></typeparam>
        /// <param name="order"></param>
        /// <param name="IsAsc"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public IQueryable<T> QueryAll<type>(Expression<Func<T, type>> order, bool IsAsc = true,Expression<Func<T, bool>>? where = null)
        {
            var iq = this.QueryAll(where);
            return IsAsc ? iq.OrderBy(order) : iq.OrderByDescending(order);
        }

        public IQueryable<T> QueryAll<type>(out int total, int skip, int take, Expression<Func<T, type>> order, bool IsAsc = true, Expression<Func<T, bool>>? where = null)
        {
            if (skip < 0)
            {
                throw new Exception("错误");
            }
            var query = this.QueryAll(order, IsAsc, where);
            total = query.Count();
            return query.Skip(skip).Take(take);


        }

        public async Task<IQueryable<T>> QueryAllAsync<type>(int skip, int take, Expression<Func<T, type>> order, bool IsAsc = true, Expression<Func<T, bool>>? where = null)
        {
            if (skip < 0)
            {
                throw new Exception("错误");
            }
            var query =await this.QueryAllAsync(order, IsAsc, where);
            return query.Skip(skip).Take(take);
        }

        public async Task<IQueryable<T>> QueryAllAsync(Expression<Func<T, bool>>? where)
        {
            IQueryable<T> iq = _dbcontext.Set<T>();
            if (where != null)
            {
                iq = iq.Where(where);
            }
            return iq;
        }

        public async Task<IQueryable<T>> QueryAllAsync<type>(Expression<Func<T, type>> order, bool IsAsc = true, Expression<Func<T, bool>>? where = null)
        {
            var iq =await this.QueryAllAsync(where);
            return IsAsc ? iq.OrderBy(order) : iq.OrderByDescending(order);
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <returns></returns>
        public int SaveChanges()
        {
            return _dbcontext.SaveChanges();
        }

        public async Task<int> SaveChangesAsync()
        {
           return await _dbcontext.SaveChangesAsync();
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="t"></param>
        public void Update(T t)
        {
            _dbcontext.Entry<T>(t).State = EntityState.Modified;
        }
        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="ie"></param>
        public void UpdateRange(IEnumerable<T> ie)
        {
            foreach (var item in ie)
            {
                _dbcontext.Entry<T>(item).State = EntityState.Modified;
            }
        }
    }
}
